home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
win
/
c
/
dib.exe
/
DIB.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-10
|
6KB
|
226 lines
#include "dib.h"
// --------------------------------------------------------------------------
// Author: Patrick Reilly 70274,161
// Function: freadDIBitmap
// Purpose: Read a DIB bitmap (.bmp) file into a HBITMAP
// Arguments: hdc - HDC for your destination (ie screen)
// lpszSpec - file specification
// fn - call-back function to modify colors. NULL if
// no color mods required.
// Returns: HBITMAP. NULL on error.
// --------------------------------------------------------------------------
HBITMAP freadDIBitmap(HDC hdc,LPSTR lpszSpec,void (*fn)(RGBQUAD far *))
{
int hFile,nbRgb,n,nRgbQuad;
HBITMAP hBitmap;
GLOBALHANDLE hmem,hbmi;
char huge *hp,huge *hptr;
LPBITMAPINFO lpbmi;
LPBITMAPFILEHEADER lpbmfh;
LPBITMAPINFOHEADER lpbmih;
DWORD dwBitmapSize;
WORD wSize;
RGBQUAD far *lprgb;
// open bitmap file //
if((hFile = _lopen(lpszSpec,OF_READ)) == -1) return 0;
// allocate block large enough to hold bitmapfileheader //
if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPFILEHEADER))))
{
_lclose(hFile);
return 0;
}
lpbmfh = (LPBITMAPFILEHEADER) GlobalLock(hmem);
// read the BITMAPFILEHEADER from file //
if(_lread(hFile,(LPSTR)lpbmfh,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
{
_lclose(hFile);
GlobalLock(hmem); GlobalFree(hmem);
return 0;
}
// ensure its a bitmap file //
if( *((char far *)lpbmfh) != 'B' || *((char far *)(lpbmfh)+1) != 'M')
{
_lclose(hFile);
GlobalLock(hmem); GlobalFree(hmem);
return 0;
}
// calculate bitmap size from BITMAPFILEHEADER //
dwBitmapSize = lpbmfh->bfSize - lpbmfh->bfOffBits;
// dont need file header any more - free memory //
GlobalLock(hmem); GlobalFree(hmem);
// ensure bitmap size is legal //
if(dwBitmapSize <= 0 || dwBitmapSize >= 67108864L)
{
_lclose(hFile);
return 0;
}
// allocate a BITMAPINFOHEADER and read from file //
if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPINFOHEADER))))
{
_lclose(hFile);
return 0;
}
lpbmih = (LPBITMAPINFOHEADER) GlobalLock(hmem);
if(_lread(hFile,(LPSTR)lpbmih,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
{
GlobalLock(hmem); GlobalFree(hmem);
_lclose(hFile);
return 0;
}
// calculate the number of RGBQUAD structures in file //
if(!(nRgbQuad = lpbmih->biClrUsed))
nRgbQuad = 1 << lpbmih->biBitCount;
// reallocate BITMAPINFOHEADER memory to hold RGBQUADs - makes it a
// BITMAPINFO structure instead
GlobalLock(hmem);
if(!(hbmi = GlobalReAlloc(hmem,sizeof(BITMAPINFOHEADER)+nRgbQuad*sizeof(RGBQUAD)+2,GMEM_MOVEABLE)))
{
GlobalFree(hmem);
_lclose(hFile);
return 0;
}
lpbmi = (LPBITMAPINFO) GlobalLock(hbmi);
// read the RGBQUAD structures. if fn not NULL, call for each RGBQUAD //
lprgb = (RGBQUAD far *) lpbmi->bmiColors;
for(n = 0; n < nRgbQuad; n++)
{
if(_lread(hFile,(LPSTR)lprgb,sizeof(RGBQUAD)) != sizeof(RGBQUAD))
{
GlobalLock(hbmi); GlobalFree(hbmi);
_lclose(hFile);
return 0;
}
if(fn)
(*fn)(lprgb);
lprgb++;
}
GlobalLock(hbmi);
// allocate memory for the bitmap data //
if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,dwBitmapSize)))
{
GlobalFree(hbmi);
_lclose(hFile);
return 0;
}
hp = hptr = (char huge *) GlobalLock(hmem);
// read the bitmap from the file, casting a huge pointer to far pointer
// for _lread and incrementing the huge pointer to keep it aligned
while(dwBitmapSize > 0)
{
wSize = (dwBitmapSize >= 32768) ? 32768 : dwBitmapSize;
if(_lread(hFile,(LPSTR)hp,wSize) != wSize)
{
GlobalLock(hmem); GlobalFree(hmem);
GlobalFree(hbmi);
_lclose(hFile);
return 0;
}
hp += wSize;
dwBitmapSize -= wSize;
}
_lclose(hFile);
// Create the DIB //
lpbmi = (LPBITMAPINFO) GlobalLock(hbmi);
hBitmap = CreateDIBitmap(hdc,&lpbmi->bmiHeader,CBM_INIT,(LPSTR)hptr,lpbmi,DIB_RGB_COLORS);
// Free up memory //
GlobalLock(hbmi); GlobalFree(hbmi);
GlobalLock(hmem); GlobalFree(hmem);
// done //
return hBitmap;
}
// --------------------------------------------------------------------------
// Function: freadDIBitmap
// Purpose: Read a DIB bitmap (.bmp) file into a HBITMAP
// Arguments: hdc - HDC for your destination (ie screen)
// lpszSpec - file specification
// Returns: HBITMAP. NULL on error.
// --------------------------------------------------------------------------
HBITMAP freadDIBitmap(HDC hdc,LPSTR lpszSpec)
{
// call freadDIBitmap(HDC,LPSTR,void (*)(RGBQUAD far *)) with a NULL fn //
return freadDIBitmap(hdc,lpszSpec,0);
}
// --------------------------------------------------------------------------
// Function: fitBitmap
// Purpose: Stretch contents of one bitmap onto another.
// Arguments: hdc - HDC for your destination (ie screen)
// hbmDest - destination bitmap handle
// hbmSrc - source bitmap handle
// Returns: HBITMAP. NULL on error.
// --------------------------------------------------------------------------
void fitBitmap(HDC hdc,HBITMAP hbmDest,HBITMAP hbmSrc)
{
HDC hdcSrc,hdcDest;
BITMAP bmSrc,bmDest;
// ensure handles are valid //
if(!hbmDest || !hbmSrc || !hdc) return;
// create DCs to access bitmaps //
hdcSrc = CreateCompatibleDC(hdc);
hdcDest = CreateCompatibleDC(hdc);
SelectObject(hdcSrc,hbmSrc);
SelectObject(hdcDest,hbmDest);
// use common mapping mode (pixel-based) //
SetMapMode(hdcSrc,MM_TEXT);
SetMapMode(hdcDest,MM_TEXT);
// get BITMAP structs for both (contains size data) //
GetObject(hbmSrc,sizeof(BITMAP),(LPSTR) &bmSrc);
GetObject(hbmDest,sizeof(BITMAP),(LPSTR) &bmDest);
// StretchBlt copy from source to destination //
StretchBlt(hdcDest,0,0,bmDest.bmWidth,bmDest.bmHeight,
hdcSrc,0,0,bmSrc.bmWidth,bmSrc.bmHeight,SRCCOPY);
// housekeeping //
DeleteDC(hdcDest);
DeleteDC(hdcSrc);
}